package com.onlyxiahui.common.utils.base.util.thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 
 * Description <br>
 * Date 2020-11-09 17:46:50<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */
public final class ThreadPoolBuilder {

	/**
	 * cpu的数量
	 */
	public static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
	/**
	 * 核心线程数 = CPU核心数 + 1
	 */
	public static final int CORE_POOL_SIZE = CPU_COUNT + 1;
	/**
	 * 线程池最大线程数 = CPU核心数 * 2 + 1
	 */
	public static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
	/**
	 * 非核心线程闲置时超时1s
	 */
	public static final long KEEP_ALIVE = 1000;

	private static CountData count = new CountData();

	static Integer getCount() {
		return count.getPlusCount();
	}

	public static ExecutorService build() {
		return build(
				// 核心线程数量
				CORE_POOL_SIZE,
				// 最大线程数量，线程池所容纳最大线程数(workQueue队列满了之后才开启)
				MAXIMUM_POOL_SIZE,
				// 当非核心线程闲置空闲时，保持活跃的时间
				KEEP_ALIVE);
	}

	public static ExecutorService build(
			int corePoolSize,
			int maximumPoolSize,
			long keepAliveTime) {
		String nameFormat = "build-" + getCount() + "-pool-%d";
		return build(
				// 核心线程数量
				corePoolSize,
				// 最大线程数量，线程池所容纳最大线程数(workQueue队列满了之后才开启)
				maximumPoolSize,
				// 当非核心线程闲置空闲时，保持活跃的时间
				keepAliveTime,
				nameFormat);

	}

	public static ExecutorService build(
			int corePoolSize,
			int maximumPoolSize,
			long keepAliveTime,
			String nameFormat) {

		return build(
				// 核心线程数量
				corePoolSize,
				// 最大线程数量，线程池所容纳最大线程数(workQueue队列满了之后才开启)
				maximumPoolSize,
				// 当非核心线程闲置空闲时，保持活跃的时间
				keepAliveTime,
				// keepAliveTime的单位 ，毫秒级
				TimeUnit.MILLISECONDS,
				// 线程任务等待队列，存储还未执行的任务
				new LinkedBlockingQueue<>(),
				// 创建线程的工厂
				new ThreadFactoryBuilder().setNameFormat(nameFormat).build(),
				// 由于达到线程边界或队列容量而阻塞时的处理程序
				new ThreadPoolExecutor.AbortPolicy());
	}

	public static ExecutorService build(
			int corePoolSize,
			int maximumPoolSize,
			long keepAliveTime,
			TimeUnit unit,
			BlockingQueue<Runnable> workQueue,
			ThreadFactory threadFactory,
			RejectedExecutionHandler handler) {
		ExecutorService executor = new ThreadPoolExecutor(
				// 核心线程数量
				corePoolSize,
				// 最大线程数量，线程池所容纳最大线程数(workQueue队列满了之后才开启)
				maximumPoolSize,
				// 当非核心线程闲置空闲时，保持活跃的时间
				keepAliveTime,
				// keepAliveTime的单位 ，毫秒级
				unit,
				// 线程任务等待队列，存储还未执行的任务
				workQueue,
				// 创建线程的工厂
				threadFactory,
				// 由于达到线程边界或队列容量而阻塞时的处理程序
				handler);
		return executor;
	}

	static class CountData {

		int count = 0;

		public int getCount() {
			return count;
		}

		public void setCount(int count) {
			this.count = count;
		}

		public void plus() {
			count = count + 1;
		}

		public synchronized int getPlusCount() {
			plus();
			return count;
		}
	}
}
